/*
 * CajaDAO.java
 *
 * Created on 13 de septiembre de 2007, 11:07 AM
 *
 * To change this template, choose Tools | Options and locate the template under
 * the Source Creation and Management node. Right-click the template and choose
 * Open. You can then make changes to the template in the Source Editor.
 */

package com.src.computec.radar.despachos.caja.dao;

import com.src.computec.radar.base.dao.GenericDAO;
import com.src.computec.radar.base.dao.exception.DAOException;
import com.src.computec.radar.despachos.base.constantes.ConstantesGenerales;
import static com.src.computec.radar.despachos.base.constantes.ConstantesGenerales.SCHEMA;
import com.src.computec.radar.despachos.caja.dto.CajaDetallleDto;
import com.src.computec.radar.despachos.caja.dto.CajaDto;
import com.src.computec.radar.despachos.caja.dto.CajaMovimientoDto;
import com.src.computec.radar.despachos.caja.exception.CajaException;
import com.src.computec.radar.despachos.despacho.dto.DespachoDto;
import com.src.computec.radar.services.utilities.dto.EnvioDto;
import com.src.computec.radar.services.utilities.dto.EnvioMovimientoDto;
import com.src.computec.radar.services.utilities.dto.NodoDto;
import com.src.log4j.logger.custom.XLogger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;

/**
 *
 * @author aocampo
 */
public class CajaDAO extends GenericDAO implements BaseCajaDAO {
    
    private static XLogger xLogger;
    
    /** Creates a new instance of CajaDAO */
    public CajaDAO() {
        this.xLogger = (XLogger) XLogger.getLogger(this.getClass().getName());
    }
    
    public CajaDto getCajaByPrimaryKey(CajaDto dto) throws DAOException {
        CajaDto cajaDto = null;
        Connection con = null;
        PreparedStatement statement = null;
        ResultSet rs = null;
        String barCode2Of5 = dto.getCodigoCaja();
        try {
            con = getConnectionDB2();
            con.setReadOnly(true);
            statement = con.prepareStatement("SELECT C.FECHA_CREACION, D.NOMBRE_DEPARTAMENTO, CP.NOMBRE_CENTRO_POBLADO, PV.RAZON_SOCIAL " +
                                             "FROM " + SCHEMA + ".CAJA C " +
                                             "INNER JOIN " + SCHEMA + ".DEPARTAMENTO D ON C.CODIGO_DEPARTAMENTO = D.CODIGO_DEPARTAMENTO " +
                                             "INNER JOIN " + SCHEMA + ".CENTRO_POBLADO CP ON C.CODIGO_DEPARTAMENTO = CP.CODIGO_DEPARTAMENTO AND C.CODIGO_MUNICIPIO = CP.CODIGO_MUNICIPIO AND C.CODIGO_CENTRO_POBLADO = CP.CODIGO_CENTROP " +
                                             "INNER JOIN " + SCHEMA + ".PROVEEDOR PV ON C.CODIGO_PROVEEDOR = PV.CODIGO_PROVEEDOR " +
                                             "WHERE CODIGO_CAJA = ?");
            int indice = 0;
            statement.setObject(++indice, dto.getCodigoCaja());
            rs = statement.executeQuery();
            while (rs.next()) {
                indice = 0;
                cajaDto = new CajaDto();
                cajaDto.setCodigoCaja(dto.getCodigoCaja());
                cajaDto.setFechaCreacion(new Date(rs.getTimestamp(++indice).getTime()));
                cajaDto.setFechaCreacionFormat(ConstantesGenerales.SIMPLE_DATE_FORMAT.format(cajaDto.getFechaCreacion()));
                cajaDto.setNombreDepartamento(rs.getString(++indice));
                cajaDto.setNombreCentroPoblado(rs.getString(++indice));
                cajaDto.setRazonSocialProveedor(rs.getString(++indice));
                while (barCode2Of5.length() < 10) {
                    barCode2Of5 = "0" + barCode2Of5;
                }
                cajaDto.setBarCode2Of5(barCode2Of5);
            }
        } 
        catch (SQLException e) {
            throw new DAOException("CajaDAO:getCajaByPrimaryKey:" + e.toString(), e);
        }
        catch (Exception e) {
            throw new DAOException("CajaDAO:getCajaByPrimaryKey:" + e.toString(), e);
        }
        finally {
            closeConnection(con, statement, rs);
        }
        return cajaDto;
    }
    
    private void insertCajaMovimiento(Connection con, CajaMovimientoDto dto) throws DAOException, CajaException {
        PreparedStatement statement = null;
        try {
            statement = con.prepareStatement("INSERT INTO " + SCHEMA + ".CAJA_MOVIMIENTO (CODIGO_CAJA, FECHA_MOVIMIENTO, CODIGO_ESTADO, UID_MOVIMIENTO) " +
                                             "VALUES (?, ?, ?, ?)");
            int indice = 0;
            statement.setObject(++indice, dto.getCodigoCaja());
            statement.setTimestamp(++indice, new Timestamp(dto.getFechaMovimiento().getTime()));
            statement.setObject(++indice, dto.getCodigoEstado());
            statement.setObject(++indice, dto.getUidMovimiento());
            statement.executeUpdate();
        } 
        catch (SQLException e) {
            throw new CajaException("CajaDAO:insertCajaMovimiento:" + e.toString(), e);
        }
        finally {
            closeConnection(null, statement);
        }
    }
    
    public String insertCaja(CajaDto dto, String ldapUser) throws DAOException {
        Connection con = null;
        PreparedStatement statement = null;
        try {
            con = getConnectionDB2();
            con.setAutoCommit(false);
            statement = con.prepareStatement("INSERT INTO " + SCHEMA + ".CAJA (CODIGO_CAJA, CODIGO_DEPARTAMENTO, CODIGO_MUNICIPIO, CODIGO_CENTRO_POBLADO, CODIGO_PROVEEDOR, CODIGO_ESTADO, FECHA_CREACION, CODIGO_DESPACHO) " +
                                             "VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
            int indice = 0;
            dto.setCodigoCaja(this.getNextId(con, SCHEMA + ".CAJA", "CODIGO_CAJA"));
            statement.setObject(++indice, dto.getCodigoCaja());
            statement.setObject(++indice, dto.getCodigoDepartamento());
            statement.setObject(++indice, dto.getCodigoMunicipio());
            statement.setObject(++indice, dto.getCodigoCentroPoblado());
            statement.setObject(++indice, dto.getCodigoProveedor());
            statement.setObject(++indice, ConstantesGenerales.CODIGO_ESTADO_CAJA_ABIERTA);
            statement.setTimestamp(++indice, new Timestamp(dto.getFechaCreacion().getTime()));
            statement.setObject(++indice, dto.getCodigoDespacho());
            statement.executeUpdate();
            CajaMovimientoDto cajaMovimientoDto = new CajaMovimientoDto();
            cajaMovimientoDto.setCodigoCaja(dto.getCodigoCaja());
            cajaMovimientoDto.setFechaMovimiento(dto.getFechaCreacion());
            cajaMovimientoDto.setCodigoEstado(ConstantesGenerales.CODIGO_ESTADO_CAJA_ABIERTA);
            cajaMovimientoDto.setUidMovimiento(ldapUser);
            this.insertCajaMovimiento(con, cajaMovimientoDto);
            con.commit();
        } 
        catch (SQLException e) {
            throw new DAOException("CajaDAO:insertCaja:" + e.toString(), e);
        }
        catch (CajaException e) {
            try {
                con.rollback();
                throw new DAOException("CajaDAO:insertCaja:" + e.toString(), e);
            }
            catch (SQLException ex) {
                throw new DAOException("CajaDAO:insertCaja:rollback:" + ex.toString(), ex);
            }
        }
        catch (Exception e) {
            try {
                con.rollback();
                throw new DAOException("CajaDAO:insertCaja:" + e.toString(), e);
            }
            catch (SQLException ex) {
                throw new DAOException("CajaDAO:insertCaja:rollback:" + ex.toString(), ex);
            }
        }
        finally {
            closeConnection(con, statement);
        }
        xLogger.info("CajaDAO:insertCaja:codigoCaja:" + dto.getCodigoCaja());
        return dto.getCodigoCaja();
    }
    
    // <editor-fold defaultstate="collapsed" desc="method disabled: insertEnvioMovimiento()">
    /*private void insertEnvioMovimiento(Connection con, EnvioMovimientoDto dto) throws DAOException, CajaException {
        PreparedStatement statement = null;
        try {
            statement = con.prepareStatement("INSERT INTO " + SCHEMA + ".ENVIO_MOVIMIENTO (CODIGO_BARRAS, CODIGO_GESTION, FECHA_MOVIMIENTO, FECHA_WEB, CODIGO_RESPONSABLE) " +
                                             "VALUES (?, ?, ?, ?, ?)");
            int indice = 0;
            statement.setObject(++indice, dto.getCodigoBarras());
            statement.setObject(++indice, dto.getCodigoGestion());
            statement.setDate(++indice, new java.sql.Date(dto.getFechaMovimiento().getTime()));
            statement.setDate(++indice, new java.sql.Date(dto.getFechaWeb().getTime()));
            statement.setObject(++indice, dto.getCodigoResponsable());
            statement.executeUpdate();
        } 
        catch (SQLException e) {
            throw new CajaException("CajaDAO:insertEnvioMovimiento:" + e.toString(), e);
        }
        finally {
            closeConnection(null, statement);
        }
    }*/
    // </editor-fold>
    
    private void insertEnvioMovimiento(Connection con, EnvioMovimientoDto dto) throws DAOException, CajaException {
        PreparedStatement statement = null;
        try {
            statement = con.prepareStatement("INSERT INTO " + SCHEMA + ".ENVIO_MOVIMIENTO (CODIGO_BARRAS, CODIGO_GESTION, FECHA_MOVIMIENTO, FECHA_WEB, CODIGO_RESPONSABLE, FECHA_PROCESO) " +
                                             "VALUES (?, ?, ?, ?, ?, (SELECT FECHA_PROCESO FROM " + SCHEMA + ".ENVIO WHERE CODIGO_BARRAS = ?))");
            int indice = 0;
            statement.setObject(++indice, dto.getCodigoBarras());
            statement.setObject(++indice, dto.getCodigoGestion());
            statement.setDate(++indice, new java.sql.Date(dto.getFechaMovimiento().getTime()));
            statement.setDate(++indice, new java.sql.Date(dto.getFechaWeb().getTime()));
            statement.setObject(++indice, dto.getCodigoResponsable());
            statement.setObject(++indice, dto.getCodigoBarras());
            statement.executeUpdate();
        } 
        catch (SQLException e) {
            throw new CajaException("CajaDAO:insertEnvioMovimiento:" + e.toString(), e);
        }
        finally {
            closeConnection(null, statement);
        }
    }
    
    private synchronized void addNumeroEnvios(CajaDto dto, int registrosUpdate) throws DAOException {
        Connection con = null;
        PreparedStatement statementQueryCajaDespacho = null;
        PreparedStatement statementUpdateDespachoNroEnvios = null;
        PreparedStatement statementUpdateCajaNroEnvios = null;
        ResultSet rs = null;
        try {
            con = getConnectionDB2();
            statementQueryCajaDespacho = con.prepareStatement("SELECT D.NRO_ENVIOS, C.NRO_ENVIOS " +
                                                              "FROM " + SCHEMA + ".CAJA C " +
                                                              "INNER JOIN " + SCHEMA + ".DESPACHO D ON C.CODIGO_DESPACHO = D.CODIGO_DESPACHO " +
                                                              "WHERE C.CODIGO_CAJA = ?");
            statementUpdateDespachoNroEnvios = con.prepareStatement("UPDATE " + SCHEMA + ".DESPACHO " +
                                                                    "SET NRO_ENVIOS = ? " +
                                                                    "WHERE CODIGO_DESPACHO = ?");
            statementUpdateCajaNroEnvios = con.prepareStatement("UPDATE " + SCHEMA + ".CAJA " +
                                                                "SET NRO_ENVIOS = ? " +
                                                                "WHERE CODIGO_CAJA = ?");
            int indice = 0;
            statementQueryCajaDespacho.setObject(++indice, dto.getCodigoCaja());
            rs = statementQueryCajaDespacho.executeQuery();
            if (rs.next()) {
                indice = 0;
                int numeroEnviosDespacho = rs.getInt(++indice);
                int numeroEnviosCaja = rs.getInt(++indice);
                try {
                    con.setAutoCommit(false);
                    indice = 0;
                    statementUpdateDespachoNroEnvios.setObject(++indice, numeroEnviosDespacho + registrosUpdate);
                    statementUpdateDespachoNroEnvios.setObject(++indice, dto.getCodigoDespacho());
                    statementUpdateDespachoNroEnvios.executeUpdate();
                    indice = 0;
                    statementUpdateCajaNroEnvios.setObject(++indice, numeroEnviosCaja + registrosUpdate);
                    statementUpdateCajaNroEnvios.setObject(++indice, dto.getCodigoCaja());
                    statementUpdateCajaNroEnvios.executeUpdate();
                    con.commit();
                }
                catch (SQLException e) {
                    try {
                        con.rollback();
                        throw new DAOException("CajaDAO:addNumeroEnvios:" + e.toString(), e);
                    }
                    catch (SQLException ex) {
                        throw new DAOException("CajaDAO:addNumeroEnvios:rollback:" + ex.toString(), ex);
                    }
                }
                catch (Exception e) {
                    try {
                        con.rollback();
                        throw new DAOException("CajaDAO:addNumeroEnvios:" + e.toString(), e);
                    }
                    catch (SQLException ex) {
                        throw new DAOException("CajaDAO:addNumeroEnvios:rollback:" + ex.toString(), ex);
                    }
                }
            }
        }
        catch (SQLException e) {
            throw new DAOException("CajaDAO:updateNumeroEnvios:" + e.toString(), e);
        }
        finally {
            closeConnection(statementQueryCajaDespacho, rs);
            closeConnection(null, statementUpdateDespachoNroEnvios);
            closeConnection(con, statementUpdateCajaNroEnvios);
        }
    }
    
    public int llenarCaja(CajaDto dto, String codigoBarrasInicial, String codigoBarrasFinal, boolean recuperacion, String ldapUser, Hashtable inconsistenciasHashTable) throws DAOException {
        Connection con = null;
        PreparedStatement statementQueryEnvios = null;
        PreparedStatement statementUpdateEnvio = null;
        PreparedStatement statementUpdateCajaNodo = null;
        ResultSet rs = null;
        Date today = new Date();
        int registrosUpdate = 0;
        try {
            con = getConnectionDB2();
            statementQueryEnvios = con.prepareStatement("SELECT E.CODIGO_BARRAS, ND.CODIGO_NODO, ND.CODIGO_DEPARTAMENTO, ND.CODIGO_MUNICIPIO, ND.CODIGO_CENTROP, ND.CODIGO_PROVEEDOR, E.CODIGO_ULTIMA_GESTION, E.CODIGO_CAJA " +
                                                        "FROM " + SCHEMA + ".ENVIO E " +
                                                        "INNER JOIN " + SCHEMA + ".NODO_DISTRIBUCION ND ON E.CODIGO_NODO = ND.CODIGO_NODO " +
                                                        "WHERE CODIGO_BARRAS BETWEEN ? AND ?");
            statementUpdateEnvio = con.prepareStatement("UPDATE " + SCHEMA + ".ENVIO " +
                                                        "SET CODIGO_ULTIMA_GESTION = ?, CODIGO_CAJA = ?, RECUPERACION = ?, CODIGO_BARRAS_INICIAL = ?, CODIGO_BARRAS_FINAL = ? " +
                                                        "WHERE CODIGO_BARRAS = ?");
            statementUpdateCajaNodo = con.prepareStatement("UPDATE " + SCHEMA + ".CAJA " +
                                                           "SET CODIGO_NODO = ? " +
                                                           "WHERE CODIGO_CAJA = ?");
            int indice = 0;
            statementQueryEnvios.setObject(++indice, codigoBarrasInicial);
            statementQueryEnvios.setObject(++indice, codigoBarrasFinal);
            rs = statementQueryEnvios.executeQuery();
            while (rs.next()) {
                indice = 0;
                boolean isValidEnvio = true;
                String codigoBarras = rs.getString(++indice);
                String codigoNodoEnvio = rs.getString(++indice);
                String codigoDepartamentoNodo = rs.getString(++indice);
                String codigoMunicipioNodo = rs.getString(++indice);
                String codigoCentroPobladoNodo = rs.getString(++indice);
                String codigoProveedor = rs.getString(++indice);
                String codigoUltimaGestion = rs.getString(++indice);
                String codigoCajaEnvio = rs.getString(++indice);
                if (codigoDepartamentoNodo != null && codigoMunicipioNodo != null && codigoCentroPobladoNodo != null) {
                    if (!codigoDepartamentoNodo.equals(dto.getCodigoDepartamento()) || !codigoMunicipioNodo.equals(dto.getCodigoMunicipio()) || !codigoCentroPobladoNodo.equals(dto.getCodigoCentroPoblado())) {
                        inconsistenciasHashTable.put(codigoBarras, ConstantesGenerales.INCONSISTENCIA_NODO_DESTINO_INVALIDO);
                        isValidEnvio = false;
                    }
                    else if (!codigoProveedor.equals(dto.getCodigoProveedor())) {
                        inconsistenciasHashTable.put(codigoBarras, ConstantesGenerales.INCONSISTENCIA_ENVIO_EM_INVALIDA);
                        isValidEnvio = false;
                    }
                    else if (!codigoUltimaGestion.equals(ConstantesGenerales.CODIGO_GESTION_ENVIO_ALISTAMIENTO) && !codigoUltimaGestion.equals(ConstantesGenerales.CODIGO_GESTION_ENVIO_DISTRIBUCION_EXTERNA) && !recuperacion) {
                        inconsistenciasHashTable.put(codigoBarras, ConstantesGenerales.INCONSISTENCIA_ENVIO_GESTION_INVALIDA);
                        isValidEnvio = false;
                    }
                    else if (codigoCajaEnvio != null && !recuperacion) {
                        inconsistenciasHashTable.put(codigoBarras, ConstantesGenerales.INCONSISTENCIA_ENVIO_CAJA_ASIGNADA);
                        isValidEnvio = false;
                    }
                    else if (dto.getCodigoNodo() != null && !dto.getCodigoNodo().equals("")) {
                        if (!codigoNodoEnvio.equals(dto.getCodigoNodo())) {
                            inconsistenciasHashTable.put(codigoBarras, ConstantesGenerales.INCONSISTENCIA_NODO_INVALIDO_CAJA);
                            isValidEnvio = false;
                        }
                    }
                    else {
                        indice = 0;
                        statementUpdateCajaNodo.setObject(++indice, codigoNodoEnvio);
                        statementUpdateCajaNodo.setObject(++indice, dto.getCodigoCaja());
                        statementUpdateCajaNodo.executeUpdate();
                        dto.setCodigoNodo(codigoNodoEnvio);
                    }
                    if (isValidEnvio) {
                        indice = 0;
                        if (!recuperacion) {
                            statementUpdateEnvio.setObject(++indice, ConstantesGenerales.CODIGO_GESTION_ENVIO_DESPACHO);
                            statementUpdateEnvio.setObject(++indice, dto.getCodigoCaja());
                            statementUpdateEnvio.setObject(++indice, ConstantesGenerales.CODIGO_NO_RECUPERACION);
                            statementUpdateEnvio.setObject(++indice, codigoBarrasInicial);
                            statementUpdateEnvio.setObject(++indice, codigoBarrasFinal);
                            statementUpdateEnvio.setObject(++indice, codigoBarras);
                            statementUpdateEnvio.executeUpdate();
                            EnvioMovimientoDto envioMovimientoDto = new EnvioMovimientoDto();
                            envioMovimientoDto.setCodigoBarras(codigoBarras);
                            envioMovimientoDto.setCodigoGestion(ConstantesGenerales.CODIGO_GESTION_ENVIO_DESPACHO);
                            envioMovimientoDto.setFechaMovimiento(today);
                            envioMovimientoDto.setFechaWeb(today);
                            envioMovimientoDto.setCodigoResponsable(ldapUser);
                            try {
                                this.insertEnvioMovimiento(con, envioMovimientoDto);
                            }
                            catch (CajaException e) {
                                xLogger.error("CajaDAO:llenarCaja:insertEnvioMovimiento:", e);
                            }
                            registrosUpdate++;
                        }
                        else {
                            if (!codigoUltimaGestion.equals(ConstantesGenerales.CODIGO_GESTION_ENVIO_ENTREGA)) {
                                statementUpdateEnvio.setObject(++indice, ConstantesGenerales.CODIGO_GESTION_ENVIO_DESPACHO);
                                statementUpdateEnvio.setObject(++indice, dto.getCodigoCaja());
                                statementUpdateEnvio.setObject(++indice, ConstantesGenerales.CODIGO_RECUPERACION);
                                statementUpdateEnvio.setObject(++indice, codigoBarrasInicial);
                                statementUpdateEnvio.setObject(++indice, codigoBarrasFinal);
                                statementUpdateEnvio.setObject(++indice, codigoBarras);
                                statementUpdateEnvio.executeUpdate();
                                EnvioMovimientoDto envioMovimientoDto = new EnvioMovimientoDto();
                                envioMovimientoDto.setCodigoBarras(codigoBarras);
                                envioMovimientoDto.setCodigoGestion(ConstantesGenerales.CODIGO_GESTION_ENVIO_DESPACHO);
                                envioMovimientoDto.setFechaMovimiento(today);
                                envioMovimientoDto.setFechaWeb(today);
                                envioMovimientoDto.setCodigoResponsable(ldapUser);
                                try {
                                    this.insertEnvioMovimiento(con, envioMovimientoDto);
                                }
                                catch (CajaException e) {
                                    xLogger.error("CajaDAO:llenarCaja:insertEnvioMovimiento:", e);
                                }
                                registrosUpdate++;
                            }
                            else {
                                inconsistenciasHashTable.put(codigoBarras, ConstantesGenerales.INCONSISTENCIA_ENVIO_GESTION_ENTREGA);
                            }
                        }
                    }
                }
                else {
                    inconsistenciasHashTable.put(codigoBarras, ConstantesGenerales.INCONSISTENCIA_NODO_DESTINO_NO_CONFIGURADO);
                    isValidEnvio = false;
                }
            }
            if (registrosUpdate > 0) {
                try {
                    this.addNumeroEnvios(dto, registrosUpdate);
                }
                catch (Exception e) {
                    xLogger.error("CajaDAO:llenarCaja:addNumeroEnvios:", e);
                }
            }
            xLogger.info("CajaDAO:llenarCaja:codigoCaja:" + dto.getCodigoCaja() + ":codigoBarrasInicial:" + codigoBarrasInicial + ":codigoBarrasFinal:" + codigoBarrasFinal + ":registrosUpdate:" + registrosUpdate);
            return registrosUpdate;
        } 
        catch (SQLException e) {
            throw new DAOException("CajaDAO:llenarCaja:" + e.toString(), e);
        }
        finally {
            closeConnection(statementQueryEnvios, rs);
            closeConnection(null, statementUpdateEnvio);
            closeConnection(con, statementUpdateCajaNodo);
        }
    }
    
    private synchronized boolean isValidEnvio(Connection con, String codigoBarras, CajaDto dto, boolean recuperacion, EnvioDto envioDto, Hashtable inconsistenciasHashTable) throws DAOException, CajaException {
        PreparedStatement statementQueryEnvios = null;
        PreparedStatement statementUpdateCajaNodo = null;
        ResultSet rs = null;
        boolean isValidEnvio = true;
        try {
            statementQueryEnvios = con.prepareStatement("SELECT  ND.CODIGO_NODO, ND.CODIGO_DEPARTAMENTO, ND.CODIGO_MUNICIPIO, ND.CODIGO_CENTROP, ND.CODIGO_PROVEEDOR, E.CODIGO_ULTIMA_GESTION, E.CODIGO_CAJA " +
                                                        "FROM " + SCHEMA + ".ENVIO E " +
                                                        "INNER JOIN " + SCHEMA + ".NODO_DISTRIBUCION ND ON E.CODIGO_NODO = ND.CODIGO_NODO " +
                                                        "WHERE E.CODIGO_BARRAS = ? ");
            statementUpdateCajaNodo = con.prepareStatement("UPDATE " + SCHEMA + ".CAJA " +
                                                           "SET CODIGO_NODO = ? " +
                                                           "WHERE CODIGO_CAJA = ?");
            int indice = 0;
            statementQueryEnvios.setObject(++indice, codigoBarras);
            rs = statementQueryEnvios.executeQuery();
            if (rs.next()) {
                indice = 0;
                String codigoNodoEnvio = rs.getString(++indice);
                String codigoDepartamentoNodo = rs.getString(++indice);
                String codigoMunicipioNodo = rs.getString(++indice);
                String codigoCentroPobladoNodo = rs.getString(++indice);
                String codigoProveedorEnvio = rs.getString(++indice);
                String codigoUltimaGestionEnvio = rs.getString(++indice);
                String codigoCajaEnvio = rs.getString(++indice);
                envioDto.setCodigoUltimaGestion(codigoUltimaGestionEnvio);
                if (codigoDepartamentoNodo != null && codigoMunicipioNodo != null && codigoCentroPobladoNodo != null) {
                    if (!codigoDepartamentoNodo.equals(dto.getCodigoDepartamento()) || !codigoMunicipioNodo.equals(dto.getCodigoMunicipio()) || !codigoCentroPobladoNodo.equals(dto.getCodigoCentroPoblado())) {
                        inconsistenciasHashTable.put(codigoBarras, ConstantesGenerales.INCONSISTENCIA_NODO_DESTINO_INVALIDO);
                        isValidEnvio = false;
                    }
                    else if (!codigoProveedorEnvio.equals(dto.getCodigoProveedor())) {
                        inconsistenciasHashTable.put(codigoBarras, ConstantesGenerales.INCONSISTENCIA_ENVIO_EM_INVALIDA);
                        isValidEnvio = false;
                    }
                    else if (!codigoUltimaGestionEnvio.equals(ConstantesGenerales.CODIGO_GESTION_ENVIO_ALISTAMIENTO) && !codigoUltimaGestionEnvio.equals(ConstantesGenerales.CODIGO_GESTION_ENVIO_DISTRIBUCION_EXTERNA) && !recuperacion) {
                        inconsistenciasHashTable.put(codigoBarras, ConstantesGenerales.INCONSISTENCIA_ENVIO_GESTION_INVALIDA);
                        isValidEnvio = false;
                    }
                    else if (codigoCajaEnvio != null && !recuperacion) {
                        inconsistenciasHashTable.put(codigoBarras, ConstantesGenerales.INCONSISTENCIA_ENVIO_CAJA_ASIGNADA);
                        isValidEnvio = false;
                    }
                    else if (dto.getCodigoNodo() != null && !dto.getCodigoNodo().equals("")) {
                        if (!codigoNodoEnvio.equals(dto.getCodigoNodo())) {
                            inconsistenciasHashTable.put(codigoBarras, ConstantesGenerales.INCONSISTENCIA_NODO_INVALIDO_CAJA);
                            isValidEnvio = false;
                        }
                    }
                    else {
                        indice = 0;
                        statementUpdateCajaNodo.setObject(++indice, codigoNodoEnvio);
                        statementUpdateCajaNodo.setObject(++indice, dto.getCodigoCaja());
                        statementUpdateCajaNodo.executeUpdate();
                        dto.setCodigoNodo(codigoNodoEnvio);
                    }
                }
                else {
                    inconsistenciasHashTable.put(codigoBarras, ConstantesGenerales.INCONSISTENCIA_NODO_DESTINO_NO_CONFIGURADO);
                    isValidEnvio = false;
                }
            }
            else {
                inconsistenciasHashTable.put(codigoBarras, ConstantesGenerales.INCONSISTENCIA_ENVIO_INEXISTENTE);
                isValidEnvio = false;
            }
            return isValidEnvio;
        } 
        catch (SQLException e) {
            throw new CajaException("CajaDAO:isValidEnvio:" + e.toString(), e);
        }
        finally {
            closeConnection(null, statementQueryEnvios);
            closeConnection(statementUpdateCajaNodo, rs);
        }
    }
    
    public int llenarCaja(CajaDto dto, List listListado, boolean recuperacion, String ldapUser, Hashtable inconsistenciasHashTable) throws DAOException {
        Connection con = null;
        PreparedStatement statementUpdateEnvio = null;
        Date today = new Date();
        EnvioDto envioDto = new EnvioDto();
        int registrosUpdate = 0;
        try {
            con = getConnectionDB2();
            statementUpdateEnvio = con.prepareStatement("UPDATE " + SCHEMA + ".ENVIO " +
                                                        "SET CODIGO_ULTIMA_GESTION = ?, CODIGO_CAJA = ?, RECUPERACION = ? " +
                                                        "WHERE CODIGO_BARRAS = ?");
            Iterator iterator = listListado.iterator();
            while (iterator.hasNext()) {
                String codigoBarras = (String) iterator.next();
                if (this.isValidEnvio(con, codigoBarras, dto, recuperacion, envioDto, inconsistenciasHashTable)) {
                    int indice = 0;
                    if (!recuperacion) {
                        statementUpdateEnvio.setObject(++indice, ConstantesGenerales.CODIGO_GESTION_ENVIO_DESPACHO);
                        statementUpdateEnvio.setObject(++indice, dto.getCodigoCaja());
                        statementUpdateEnvio.setObject(++indice, ConstantesGenerales.CODIGO_NO_RECUPERACION);
                        statementUpdateEnvio.setObject(++indice, codigoBarras);
                        statementUpdateEnvio.executeUpdate();
                        EnvioMovimientoDto envioMovimientoDto = new EnvioMovimientoDto();
                        envioMovimientoDto.setCodigoBarras(codigoBarras);
                        envioMovimientoDto.setCodigoGestion(ConstantesGenerales.CODIGO_GESTION_ENVIO_DESPACHO);
                        envioMovimientoDto.setFechaMovimiento(today);
                        envioMovimientoDto.setFechaWeb(today);
                        envioMovimientoDto.setCodigoResponsable(ldapUser);
                        try {
                            this.insertEnvioMovimiento(con, envioMovimientoDto);
                        }
                        catch (CajaException e) {
                            xLogger.error("CajaDAO:llenarCaja:insertEnvioMovimiento:", e);
                        }
                        registrosUpdate++;
                    }
                    else {
                        if (envioDto.getCodigoUltimaGestion() != null && !envioDto.getCodigoUltimaGestion().equals("") && !envioDto.getCodigoUltimaGestion().equals(ConstantesGenerales.CODIGO_GESTION_ENVIO_ENTREGA)) {
                            statementUpdateEnvio.setObject(++indice, ConstantesGenerales.CODIGO_GESTION_ENVIO_DESPACHO);
                            statementUpdateEnvio.setObject(++indice, dto.getCodigoCaja());
                            statementUpdateEnvio.setObject(++indice, ConstantesGenerales.CODIGO_RECUPERACION);
                            statementUpdateEnvio.setObject(++indice, codigoBarras);
                            statementUpdateEnvio.executeUpdate();
                            EnvioMovimientoDto envioMovimientoDto = new EnvioMovimientoDto();
                            envioMovimientoDto.setCodigoBarras(codigoBarras);
                            envioMovimientoDto.setCodigoGestion(ConstantesGenerales.CODIGO_GESTION_ENVIO_DESPACHO);
                            envioMovimientoDto.setFechaMovimiento(today);
                            envioMovimientoDto.setFechaWeb(today);
                            envioMovimientoDto.setCodigoResponsable(ldapUser);
                            try {
                                this.insertEnvioMovimiento(con, envioMovimientoDto);
                            }
                            catch (CajaException e) {
                                xLogger.error("CajaDAO:llenarCaja:insertEnvioMovimiento:", e);
                            }
                            registrosUpdate++;
                        }
                        else {
                            inconsistenciasHashTable.put(codigoBarras, ConstantesGenerales.INCONSISTENCIA_ENVIO_GESTION_ENTREGA);
                        }
                    }
                }
            }
            if (registrosUpdate > 0) {
                try {
                    this.addNumeroEnvios(dto, registrosUpdate);
                }
                catch (Exception e) {
                    xLogger.error("CajaDAO:llenarCaja:addNumeroEnvios:", e);
                }
            }
            xLogger.info("CajaDAO:llenarCaja:codigoCaja:" + dto.getCodigoCaja() + ":registrosUpdate:" + registrosUpdate);
            return registrosUpdate;
        }
        catch (SQLException e) {
            throw new DAOException("CajaDAO:llenarCaja:" + e.toString(), e);
        }
        catch (CajaException e) {
            throw new DAOException("CajaDAO:llenarCaja:" + e.toString(), e);
        }
        finally {
            closeConnection(con, statementUpdateEnvio);
        }
    }
    
    private synchronized void extraerEnvioCaja(Connection con, String codigoBarras) throws DAOException, CajaException {
        PreparedStatement statement = null;
        ResultSet rs = null;
        try {
            statement = con.prepareStatement("UPDATE " + SCHEMA + ".ENVIO " +
                                             "SET CODIGO_ULTIMA_GESTION = ?, CODIGO_CAJA = ?, RECUPERACION = ?, CODIGO_BARRAS_INICIAL = ?, CODIGO_BARRAS_FINAL = ? " +
                                             "WHERE CODIGO_BARRAS = ?");
            int indice = 0;
            statement.setObject(++indice, ConstantesGenerales.CODIGO_GESTION_ENVIO_ALISTAMIENTO);
            statement.setNull(++indice, java.sql.Types.INTEGER);
            statement.setNull(++indice, java.sql.Types.SMALLINT);
            statement.setNull(++indice, java.sql.Types.BIGINT);
            statement.setNull(++indice, java.sql.Types.BIGINT);
            statement.setObject(++indice, codigoBarras);
            statement.executeUpdate();
        }
        catch (SQLException e) {
            throw new CajaException("CajaDAO:extraerEnvioCaja:" + e.toString(), e);
        }
        finally {
            closeConnection(null, statement, rs);
        }
    }
    
    public void vaciarCaja(List listDetallesLabel, CajaDto dto) throws DAOException {
        Connection con = null;
        PreparedStatement statement = null;
        ResultSet rs = null;
        int registrosUpdate = 0;
        try {
            con = getConnectionDB2();
            statement = con.prepareStatement("SELECT E.CODIGO_BARRAS " +
                                             "FROM " + SCHEMA + ".ENVIO E " +
                                             "INNER JOIN " + SCHEMA + ".ORDEN_PROCESO OP ON E.NUMERO_ORDEN = OP.NUMERO_ORDEN " +
                                             "WHERE E.CODIGO_CAJA = ? AND OP.NUMERO_ORDEN = ? AND E.CODIGO_NODO = ? AND OP.CODIGO_CLIENTE = ? AND OP.CODIGO_PRODUCTO = ? AND OP.CICLO = ?");
            Iterator iterator = listDetallesLabel.iterator();
            while (iterator.hasNext()) {
                int indice = 0;
                String[] tokens = ((String) iterator.next()).split(";");
                statement.setObject(++indice, tokens[0]);
                statement.setObject(++indice, tokens[1]);
                statement.setObject(++indice, tokens[2]);
                statement.setObject(++indice, tokens[3]);
                statement.setObject(++indice, tokens[4]);
                statement.setObject(++indice, tokens[5]);
                rs = statement.executeQuery();
                try {
                    con.setAutoCommit(false);
                    while (rs.next()) {
                        indice = 0;
                        String codigoBarras = rs.getString(++indice);
                        this.extraerEnvioCaja(con, codigoBarras);
                        registrosUpdate++;
                    }
                    con.commit();
                }
                catch (CajaException e) {
                    try {
                        con.rollback();
                        throw new DAOException("CajaDAO:vaciarCaja:" + e.toString(), e);
                    }
                    catch (SQLException ex) {
                        throw new DAOException("CajaDAO:vaciarCaja:rollback:" + ex.toString(), ex);
                    }
                }
                catch (Exception e) {
                    try {
                        con.rollback();
                        throw new DAOException("CajaDAO:vaciarCaja:" + e.toString(), e);
                    }
                    catch (SQLException ex) {
                        throw new DAOException("CajaDAO:vaciarCaja:rollback:" + ex.toString(), ex);
                    }
                }
            }
            if (registrosUpdate > 0) {
                try {
                    this.addNumeroEnvios(dto, (registrosUpdate * -1));
                    xLogger.info("CajaDAO:vaciarCaja:codigoCaja:" + dto.getCodigoCaja() + ":addNumeroEnvios:" + (registrosUpdate * -1));
                }
                catch (Exception e) {
                    xLogger.error("CajaDAO:vaciarCaja:addNumeroEnvios:", e);
                }
            }
        }
        catch (SQLException e) {
            throw new DAOException("CajaDAO:vaciarCaja:" + e.toString(), e);
        }
        finally {
            closeConnection(con, statement, rs);
        }
    }
    
    public List getNodosByCaja(CajaDto dto) throws DAOException {
        List listNodos = new ArrayList();
        Connection con = null;
        PreparedStatement statement = null;
        ResultSet rs = null;
        try {
            con = getConnectionDB2();
            con.setReadOnly(true);
            statement = con.prepareStatement("SELECT E.CODIGO_NODO, ND.NOMBRE_NODO " +
                                             "FROM " + SCHEMA + ".ENVIO E " +
                                             "INNER JOIN " + SCHEMA + ".NODO_DISTRIBUCION ND ON E.CODIGO_NODO = ND.CODIGO_NODO " +
                                             "WHERE E.CODIGO_CAJA = ? " +
                                             "GROUP BY E.CODIGO_NODO, ND.NOMBRE_NODO");
            int indice = 0;
            statement.setObject(++indice, dto.getCodigoCaja());
            rs = statement.executeQuery();
            while (rs.next()) {
                indice = 0;
                NodoDto nodoDto = new NodoDto();
                nodoDto.setCodigoNodo(rs.getString(++indice));
                nodoDto.setNombreNodo(rs.getString(++indice));
                listNodos.add(nodoDto);
            }
        } 
        catch (SQLException e) {
            throw new DAOException("CajaDAO:getNodosByCaja:" + e.toString(), e);
        }
        finally {
            closeConnection(con, statement, rs);
        }
        return listNodos;
    }
    
    public List getDetallesLabel(CajaDto dto) throws DAOException {
        List listDetallesLabel = new ArrayList();
        Connection con = null;
        PreparedStatement statement = null;
        ResultSet rs = null;
        try {
            con = getConnectionDB2();
            con.setReadOnly(true);
            statement = con.prepareStatement("SELECT E.CODIGO_CAJA, E.NUMERO_ORDEN, E.CODIGO_NODO, E.CODIGO_CLIENTE, E.CODIGO_PRODUCTO, OP.CICLO, ND.NOMBRE_NODO, C.RAZON_SOCIAL, P.DESCRIPCION_PRODUCTO, COUNT(E.CODIGO_BARRAS) AS CANTIDAD " +
                                             "FROM " + SCHEMA + ".ENVIO E " +
                                             "INNER JOIN " + SCHEMA + ".NODO_DISTRIBUCION ND ON E.CODIGO_NODO = ND.CODIGO_NODO " +
                                             "INNER JOIN " + SCHEMA + ".CLIENTE C ON E.CODIGO_CLIENTE = C.CODIGO_CLIENTE " +
                                             "INNER JOIN " + SCHEMA + ".PRODUCTO P ON E.CODIGO_CLIENTE = P.CODIGO_CLIENTE AND E.CODIGO_PRODUCTO = P.CODIGO_PRODUCTO " +
                                             "INNER JOIN " + SCHEMA + ".ORDEN_PROCESO OP ON E.NUMERO_ORDEN = OP.NUMERO_ORDEN " +
                                             "WHERE E.CODIGO_CAJA = ? " +
                                             "GROUP BY E.CODIGO_CAJA, E.NUMERO_ORDEN, E.CODIGO_NODO, E.CODIGO_CLIENTE, E.CODIGO_PRODUCTO, OP.CICLO, ND.NOMBRE_NODO, C.RAZON_SOCIAL, P.DESCRIPCION_PRODUCTO");
            int indice = 0;
            statement.setObject(++indice, dto.getCodigoCaja());
            rs = statement.executeQuery();
            while (rs.next()) {
                indice = 0;
                CajaDetallleDto cajaDetallleDto = new CajaDetallleDto();
                cajaDetallleDto.setCodigoCaja(rs.getString(++indice));
                cajaDetallleDto.setNumeroOrden(rs.getString(++indice));
                cajaDetallleDto.setCodigoNodo(rs.getString(++indice));
                cajaDetallleDto.setCodigoCliente(rs.getString(++indice));
                cajaDetallleDto.setCodigoProducto(rs.getString(++indice));
                cajaDetallleDto.setCiclo(rs.getString(++indice));
                cajaDetallleDto.setNombreNodo(rs.getString(++indice));
                cajaDetallleDto.setRazonSocialCliente(rs.getString(++indice));
                cajaDetallleDto.setDescripcionProducto(rs.getString(++indice));
                cajaDetallleDto.setCantidad(rs.getString(++indice));
                listDetallesLabel.add(cajaDetallleDto);
            }
        } 
        catch (SQLException e) {
            throw new DAOException("CajaDAO:getDetallesLabel:" + e.toString(), e);
        }
        finally {
            closeConnection(con, statement, rs);
        }
        return listDetallesLabel;
    }
    
    public List getCajasByDespacho(DespachoDto dto) throws DAOException {
        List listCajas = new ArrayList();
        Connection con = null;
        PreparedStatement statement = null;
        ResultSet rs = null;
        try {
            con = getConnectionDB2();
            con.setReadOnly(true);
            statement = con.prepareStatement("SELECT C.CODIGO_CAJA, C.CODIGO_DEPARTAMENTO, C.CODIGO_MUNICIPIO, C.CODIGO_CENTRO_POBLADO, C.CODIGO_PROVEEDOR, C.CODIGO_ESTADO, C.FECHA_CREACION, C.CODIGO_DESPACHO, C.CODIGO_NODO, C.NRO_ENVIOS, D.NOMBRE_DEPARTAMENTO, CP.NOMBRE_CENTRO_POBLADO, PV.RAZON_SOCIAL, EC.NOMBRE_ESTADO, ND.NOMBRE_NODO " +
                                             "FROM " + SCHEMA + ".CAJA C " +
                                             "INNER JOIN " + SCHEMA + ".DEPARTAMENTO D ON C.CODIGO_DEPARTAMENTO = D.CODIGO_DEPARTAMENTO " +
                                             "INNER JOIN " + SCHEMA + ".CENTRO_POBLADO CP ON C.CODIGO_DEPARTAMENTO = CP.CODIGO_DEPARTAMENTO AND C.CODIGO_MUNICIPIO = CP.CODIGO_MUNICIPIO AND C.CODIGO_CENTRO_POBLADO = CP.CODIGO_CENTROP " +
                                             "INNER JOIN " + SCHEMA + ".PROVEEDOR PV ON C.CODIGO_PROVEEDOR = PV.CODIGO_PROVEEDOR " +
                                             "INNER JOIN " + SCHEMA + ".ESTADO_CAJA EC ON C.CODIGO_ESTADO = EC.CODIGO_ESTADO " +
                                             "INNER JOIN " + SCHEMA + ".NODO_DISTRIBUCION ND ON COALESCE(C.CODIGO_NODO,0) = ND.CODIGO_NODO " +
                                             "WHERE C.CODIGO_DESPACHO = ? " +
                                             "ORDER BY C.FECHA_CREACION DESC");
            int indice = 0;
            statement.setObject(++indice, dto.getCodigoDespacho());
            rs = statement.executeQuery();
            while (rs.next()) {
                indice = 0;
                CajaDto cajaDto = new CajaDto();
                cajaDto.setCodigoCaja(rs.getString(++indice));
                cajaDto.setCodigoDepartamento(rs.getString(++indice));
                cajaDto.setCodigoMunicipio(rs.getString(++indice));
                cajaDto.setCodigoCentroPoblado(rs.getString(++indice));
                cajaDto.setCodigoProveedor(rs.getString(++indice));
                cajaDto.setCodigoEstado(rs.getString(++indice));
                cajaDto.setFechaCreacion(new Date(rs.getTimestamp(++indice).getTime()));
                cajaDto.setCodigoDespacho(rs.getString(++indice));
                cajaDto.setCodigoNodo(rs.getString(++indice));
                cajaDto.setNumeroEnvios(rs.getInt(++indice));
                cajaDto.setFechaCreacionFormat(ConstantesGenerales.SIMPLE_DATE_FORMAT.format(cajaDto.getFechaCreacion()));
                cajaDto.setNombreDepartamento(rs.getString(++indice));
                cajaDto.setNombreCentroPoblado(rs.getString(++indice));
                cajaDto.setRazonSocialProveedor(rs.getString(++indice));
                cajaDto.setNombreEstado(rs.getString(++indice));
                cajaDto.setNombreNodo(rs.getString(++indice));
                if (cajaDto.getCodigoEstado().equals(ConstantesGenerales.CODIGO_ESTADO_CAJA_ABIERTA)) {
                    cajaDto.setAbierta(true);
                    if (!this.hasCloseCaja(cajaDto)) {
                        cajaDto.setEliminable(true);
                    }
                    else {
                        cajaDto.setEliminable(false);
                    }
                }
                else {
                    cajaDto.setAbierta(false);
                    cajaDto.setEliminable(false);
                }
                listCajas.add(cajaDto);
            }
        } 
        catch (SQLException e) {
            throw new DAOException("CajaDAO:getCajasByDespacho:" + e.toString(), e);
        }
        finally {
            closeConnection(con, statement, rs);
        }
        return listCajas;
    }
    
    public boolean hasCloseCaja(CajaDto dto) throws DAOException {
        Connection con = null;
        PreparedStatement statement = null;
        ResultSet rs = null;
        try {
            con = getConnectionDB2();
            con.setReadOnly(true);
            statement = con.prepareStatement("SELECT COUNT(CODIGO_BARRAS) " +
                                             "FROM " + SCHEMA + ".ENVIO " +
                                             "WHERE CODIGO_CAJA = ?");
            int indice = 0;
            statement.setObject(++indice, dto.getCodigoCaja());
            rs = statement.executeQuery();
            if (rs.next()) {
                indice = 0;
                int numeroEnvios = rs.getInt(++indice);
                if (numeroEnvios > 0) {
                    return true;
                }
                else {
                    return false;
                }
            }
            else {
                return false;
            }
        } 
        catch (SQLException e) {
            throw new DAOException("CajaDAO:hasCloseCaja:" + e.toString(), e);
        }
        finally {
            closeConnection(con, statement, rs);
        }
    }
    
    public void cambiarEstadoCaja(CajaDto dto, String ldapUser) throws DAOException {
        Connection con = null;
        PreparedStatement statement = null;
        try {
            con = getConnectionDB2();
            con.setAutoCommit(false);
            statement = con.prepareStatement("UPDATE " + SCHEMA + ".CAJA " +
                                             "SET CODIGO_ESTADO = ? " +
                                             "WHERE CODIGO_CAJA = ?");
            int indice = 0;
            statement.setObject(++indice, dto.getCodigoEstado());
            statement.setObject(++indice, dto.getCodigoCaja());
            statement.executeUpdate();
            CajaMovimientoDto cajaMovimientoDto = new CajaMovimientoDto();
            cajaMovimientoDto.setCodigoCaja(dto.getCodigoCaja());
            cajaMovimientoDto.setFechaMovimiento(new Date());
            cajaMovimientoDto.setCodigoEstado(dto.getCodigoEstado());
            cajaMovimientoDto.setUidMovimiento(ldapUser);
            this.insertCajaMovimiento(con, cajaMovimientoDto);
            con.commit();
        } 
        catch (SQLException e) {
            throw new DAOException("CajaDAO:cambiarEstadoCaja:" + e.toString(), e);
        }
        catch (CajaException e) {
            try {
                con.rollback();
                throw new DAOException("CajaDAO:cambiarEstadoCaja:" + e.toString(), e);
            }
            catch (SQLException ex) {
                throw new DAOException("CajaDAO:cambiarEstadoCaja:rollback:" + ex.toString(), ex);
            }
        }
        catch (Exception e) {
            try {
                con.rollback();
                throw new DAOException("CajaDAO:cambiarEstadoCaja:" + e.toString(), e);
            }
            catch (SQLException ex) {
                throw new DAOException("CajaDAO:cambiarEstadoCaja:rollback:" + ex.toString(), ex);
            }
        }
        finally {
            closeConnection(con, statement);
        }
    }
    
    public int validarCaja(CajaDto dto, List listListado, Hashtable validacionesHashTable) throws DAOException {
        Connection con = null;
        PreparedStatement statement = null;
        ResultSet rs = null;
        int registrosValidos = 0;
        try {
            con = getConnectionDB2();
            con.setReadOnly(true);
            statement = con.prepareStatement("SELECT CODIGO_CAJA " +
                                             "FROM " + SCHEMA + ".ENVIO " +
                                             "WHERE CODIGO_BARRAS = ?");
            Iterator iterator = listListado.iterator();
            while (iterator.hasNext()) {
                String codigoBarras = (String) iterator.next();
                int indice = 0;
                statement.setObject(++indice, codigoBarras);
                rs = statement.executeQuery();
                if (rs.next()) {
                    indice = 0;
                    String codigoCaja = rs.getString(++indice);
                    if (codigoCaja != null && !codigoCaja.equals("")) {
                        if (codigoCaja.equals(dto.getCodigoCaja())) {
                            registrosValidos++;
                        }
                        else {
                            validacionesHashTable.put(codigoBarras, ConstantesGenerales.VALIDACION_ENVIO_OTRA_CAJA_ASOCIADA);
                        }
                    }
                    else {
                        validacionesHashTable.put(codigoBarras, ConstantesGenerales.VALIDACION_ENVIO_SIN_CAJA_ASOCIADA);
                    }
                }
                else {
                    validacionesHashTable.put(codigoBarras, ConstantesGenerales.VALIDACION_ENVIO_INEXISTENTE);
                }
            }
            return registrosValidos;
        } 
        catch (SQLException e) {
            throw new DAOException("CajaDAO:validarCaja:" + e.toString(), e);
        }
        finally {
            closeConnection(con, statement, rs);
        }
    }
    
    // <editor-fold defaultstate="collapsed" desc="method disabled: transferCajas()">
    /*public void transferCajas(String codigoDespacho, List listCajasSeleccion) throws DAOException {
        Connection con = null;
        PreparedStatement statement = null;
        try {
            con = getConnectionDB2();
            statement = con.prepareStatement("UPDATE " + SCHEMA + ".CAJA " +
                                             "SET CODIGO_DESPACHO = ? " +
                                             "WHERE CODIGO_CAJA = ?");
            Iterator iterator = listCajasSeleccion.iterator();
            while (iterator.hasNext()) {
                int indice = 0;
                String codigoCaja = (String) iterator.next();
                statement.setObject(++indice, codigoDespacho);
                statement.setObject(++indice, codigoCaja);
                statement.executeUpdate();
            }
        } 
        catch (SQLException e) {
            throw new DAOException("CajaDAO:transferCajas:" + e.toString(), e);
        }
        finally {
            closeConnection(con, statement);
        }
    }*/
    // </editor-fold>
    
    public void deleteCaja(CajaDto dto) throws DAOException {
        Connection con = null;
        PreparedStatement statementCajaMovimiento = null;
        PreparedStatement statementCaja = null;
        try {
            con = getConnectionDB2();
            con.setAutoCommit(false);
            statementCajaMovimiento = con.prepareStatement("DELETE " +
                                                           "FROM " + SCHEMA + ".CAJA_MOVIMIENTO " +
                                                           "WHERE CODIGO_CAJA = ?");
            statementCaja = con.prepareStatement("DELETE " +
                                                 "FROM " + SCHEMA + ".CAJA " +
                                                 "WHERE CODIGO_CAJA = ?");
            int indice = 0;
            statementCajaMovimiento.setObject(++indice, dto.getCodigoCaja());
            statementCajaMovimiento.executeUpdate();
            indice = 0;
            statementCaja.setObject(++indice, dto.getCodigoCaja());
            statementCaja.executeUpdate();
            con.commit();
            xLogger.info("CajaDAO:deleteCaja:codigoCaja:" + dto.getCodigoCaja());
        } 
        catch (SQLException e) {
            try {
                con.rollback();
                throw new DAOException("CajaDAO:deleteCaja:" + e.toString(), e);
            }
            catch (SQLException ex) {
                throw new DAOException("CajaDAO:deleteCaja:rollback:" + ex.toString(), ex);
            }
        }
        catch (Exception e) {
            try {
                con.rollback();
                throw new DAOException("CajaDAO:deleteCaja:" + e.toString(), e);
            }
            catch (SQLException ex) {
                throw new DAOException("CajaDAO:deleteCaja:rollback:" + ex.toString(), ex);
            }
        }
        finally {
            closeConnection(null, statementCajaMovimiento);
            closeConnection(con, statementCaja);
        }
    }
}